package com.example.demo.network


import android.content.Context
import android.util.Log
import com.example.demo.BuildConfig
import com.example.featuresdk.core.EnvConfiguration
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Qualifier
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
class HttpClientProvider {

    companion object{
        const val TAG = "HttpClientProvider"
    }

    @Qualifier
    annotation class MockHttpClient
//    @Qualifier
//    annotation class MockRetrofit
//
//    @Qualifier
//    annotation class HttpClient
//
//    @Qualifier
//    annotation class MemoryCache
//
//    @Qualifier
//    annotation class MemoryCacheHttpClient
//
//    @Qualifier
//    annotation class CacheHttpClient

    @Provides
    @Singleton
    fun retrofit(httpClient: OkHttpClient, envConfiguration: EnvConfiguration) : Retrofit {
        return  Retrofit.Builder()
            .client(httpClient)
            .baseUrl(envConfiguration.hostname)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    @Provides
    @Singleton
    fun httpClient(@ApplicationContext context: Context, envConfiguration: EnvConfiguration) :OkHttpClient {

        return if(BuildConfig.MockHttpClient){
            mockHttpClient(context, envConfiguration)
        }else{
            OkHttpClient.Builder()
                .addInterceptor(HttpLoggingInterceptor().apply {
                    level = HttpLoggingInterceptor.Level.BODY
                }).build()
        }
    }

    @MockHttpClient
    @Provides
    @Singleton
    fun mockHttpClient(context: Context, envConfiguration: EnvConfiguration) :OkHttpClient {

       Log.i(TAG,"****building mock httpClient")

        return OkHttpClient.Builder()
            .addInterceptor(Interceptor { chain ->

                var filename = chain.request().url.toString().replace(envConfiguration.hostname!!,"").replace("/","-")
                if(filename.startsWith("-")){
                    filename = filename.substring(1)
                }
                Log.i(TAG,"**********Request=${chain.request().url.toString()}, file=${filename}.json")

                Response.Builder()
                    .request(chain.request())
                    .protocol(Protocol.HTTP_1_1)
                    .code(200)
                    .body(context.assets.open("${filename}.json").reader().readText().toResponseBody("application/json".toMediaType()))
                    .message("mock json")
                    .build()

            })
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            }).build()
    }
/*
    @Provides
    @MemoryCache
    @Singleton
    fun memoryCache(): LruCache<String,String> = LruCache<String,String>(10)

    @MemoryCacheHttpClient
    @Provides
    @Singleton
    fun memoryCacheHttpClient(@MemoryCache memoryCache:LruCache<String,String>) : OkHttpClient{
        return OkHttpClient.Builder()
            .addInterceptor { chain ->

                val request: Request = chain.request()
                val response: Response

                var cachedResponse = memoryCache.get(request.url.toString())

                if(cachedResponse == null){

                    Log.i("No cache","Network request************")

                    response = chain.proceed(request)

                    if(response.isSuccessful){
                        cachedResponse = response.body!!.string()
                        memoryCache.put(request.url.toString(),cachedResponse)
                    }else{
                        cachedResponse = ""
                    }
                }

                Log.i("Cache", "#####***return result*********")

                Response.Builder()
                    .request(chain.request())
                    .protocol(Protocol.HTTP_1_1)
                    .code(200)
                    .body(cachedResponse.toResponseBody("application/json".toMediaType()))
                    .message("cached result")
                    .build()
            }
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build()
    }

    @CacheHttpClient
    @Provides
    @Singleton
    fun cacheHttpClient() : OkHttpClient {

        return OkHttpClient.Builder()
            .cache(Cache(File(Environment.getDataDirectory(), "http_response_cache"),102400))
            .addNetworkInterceptor { chain ->
                var request: Request = chain.request()

                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build()

                val response: Response = chain.proceed(request)

                response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control","max-age=60")
                    .build()
            }
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build()
    }
*/

}